package cn.ycc1.springaop.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * @author ycc
 * @date 2024/11/12
 *
 * *: 表示任意字符
 * ..
 * 1. 参数位置，表示多个参数，任意类型
 * 2. 类型（包）位置，代表多个层级
 *
 * AOP的实现方式：
 * 一. @Aspect注解实现  依赖-》定义需要切入的注解-》定义切面类
 *
 * 二. AbstractPointcutAdvisor 实现
 * 1. 定义需要切入的注解
 * 2. 定义拦截器
 * 3. 配置Advisor
 * 4. 注册Advisor
 */
@Component
@Aspect
public class LogAspect {

    /**
     * 定义切点，指定切面执行的位置
     */
    @Pointcut("execution(* cn.ycc1.springaop.calculator.MathCalculator.*(..))")
    public void pointCut() {}

    /**
     * JoinPoint 包含当前目标方法的所有信息
     * @param joinPoint
     */
    @Before("pointCut()")
    public void before(JoinPoint joinPoint) {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        // 方法名
        String name = methodSignature.getName();
        // 参数
        Object[] args = joinPoint.getArgs();

        System.out.println("切面日志执行方法【 "+ name +" 】：before  参数列表： 【 "+ Arrays.toString(args) +" 】");
    }

    @After("pointCut()")
    public void after() {
        System.out.println("切面日志执行：after");
    }

}
